﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Douban.Api;
using Douban.Core.Menus;
using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.Composite.Presentation.Commands;
using Douban.Api.Broadcast;
using Douban.Api.User;
using Douban.Modules.Broadcast.ViewModels;
using Microsoft.Practices.Composite.Regions;
using Douban.Core;
using System.ComponentModel;
using System.Windows.Threading;
using Douban.Core.Settings;

namespace Douban.Modules.Broadcast
{
    public class BroadcastController
    {
        private DoubanService _doubanService;
        private UserDetail _currentUser;
        private IRegionManager _regionManager;
        private IMenuManager _menuManager;
        private ISettingManager _settingManager;
        private IBroadcastViewModel _broadcast;
        private IBroadcastViewModel _contactBroadcast;
        private DispatcherTimer _timer;
        private const int MiniblogsPerPage = 20;
        private const double RefreshInterval = 2.0;

        public BroadcastController(
            DoubanService doubanService, 
            IRegionManager regionManager, 
            IMenuManager menuManager,
            ISettingManager settingManager)
        {
            _doubanService = doubanService;
            _regionManager = regionManager;
            _menuManager = menuManager;
            _settingManager = settingManager;
        }

        public void Run()
        {
            InitializeBroadcastFunctions();
            RegisterMenus();
            RegisterViewWithRegion();
            SetRefreshTimer();
        }

        private void SetRefreshTimer()
        {
            _settingManager.Register("RefreshFrequency",
                (name, value) =>
                {
                    if (_timer != null) _timer.Stop();

                    _timer = new DispatcherTimer();
                    _timer.Interval = TimeSpan.FromMinutes((double)value);
                    _timer.Tick += _timer_Tick;

                    _timer.Start();
                });

            _timer = new DispatcherTimer();
            _timer.Interval = TimeSpan.FromMinutes(_settingManager.Settings.RefreshFrequency);
            _timer.Tick += _timer_Tick;

            _timer.Start();
        }

        private void _timer_Tick(object sender, EventArgs e)
        {
            Update();
        }

        private void Update()
        {
            BackgroundWorker bgWorker = new BackgroundWorker();
            bgWorker.DoWork += bgWorker_DoWork;
            bgWorker.RunWorkerCompleted += bgWorker_RunWorkerCompleted;
            bgWorker.RunWorkerAsync(_currentUser.Id);
        }

        private void InitializeBroadcastFunctions()
        {
            _currentUser = _doubanService.UserService.CurrentUser;
            _broadcast = ServiceLocator.Current.GetInstance<IBroadcastViewModel>();
            _contactBroadcast = ServiceLocator.Current.GetInstance<IBroadcastViewModel>();

            Update();
        }

        private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MiniblogFeed[] result = (MiniblogFeed[])e.Result;
            _broadcast.MiniblogFeed = result[0];
            _contactBroadcast.MiniblogFeed = result[1];
        }

        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            string userId = e.Argument as string;
            BroadcastServiceProvider broadcastService = _doubanService.BroadcastService;
            e.Result = new MiniblogFeed[] 
            {
                broadcastService.GetMiniblogs(userId, 1, MiniblogsPerPage),
                broadcastService.GetContactMiniblogs(userId, 1, MiniblogsPerPage)
            };
        }

        private void RegisterViewWithRegion()
        {
            _regionManager.RegisterViewWithRegion(RegionNames.MainRegion, () => _broadcast.View);
            _regionManager.RegisterViewWithRegion(RegionNames.MainRegion, () => _contactBroadcast.View);
        }

        private void RegisterMenus()
        {
            IRegion region = _regionManager.Regions[RegionNames.MainRegion];

            MenuItem broadcastMenu = new MenuItem
            {
                Name = "广播",
                Icon = "pack://application:,,,/Douban.Modules.Broadcast;Component/Images/broadcast.png",
                Command = new DelegateCommand<object>(obj => { region.Activate(_broadcast.View); })
            };

            MenuItem contactBroadcastMenu = new MenuItem
            {
                Name = "友邻广播",
                Icon = "pack://application:,,,/Douban.Modules.Broadcast;Component/Images/broadcast.png",
                Command = new DelegateCommand<object>(obj => { region.Activate(_contactBroadcast.View); })
            };

            _menuManager.Add(broadcastMenu);
            _menuManager.Add(contactBroadcastMenu);
        }
    }
}
